package cn.bincker.mybatis.encrypt.core.impl;

import cn.bincker.mybatis.encrypt.core.EncryptCache;
import cn.bincker.mybatis.encrypt.core.EncryptCacheManager;
import cn.bincker.mybatis.encrypt.entity.EncryptProperty;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class EncryptCacheManagerImpl implements EncryptCacheManager {
    private final Map<String, EncryptCache<?>> cacheMap = new ConcurrentHashMap<>();
    private final List<EncryptCache<?>> encryptCaches;
    private final Set<EncryptProperty> noCacheProperties = Collections.newSetFromMap(new ConcurrentHashMap<>());

    public EncryptCacheManagerImpl(List<EncryptCache<?>> encryptCaches) {
        this.encryptCaches = encryptCaches;
    }

    @Override
    public EncryptCache<?> getCache(EncryptProperty property) {
        if (noCacheProperties.contains(property)) return null;
        var key = property.getType().getName() + "." + property.getName();
        var cache = cacheMap.get(key);
        if (cache != null) return cache;
        for (var cacheItem : encryptCaches) {
            if (cacheItem.support(property)){
                cacheMap.put(key, cacheItem);
                return cacheItem;
            }
        }
        noCacheProperties.add(property);
        return null;
    }
}
